home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / storage / lmgr / lmgr.c next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  22.7 KB  |  999 lines

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    lmgr.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    POSTGRES lock manager code
  7.  *
  8.  *   INTERFACE ROUTINES
  9.  *
  10.  *   NOTES
  11.  *
  12.  *   IDENTIFICATION
  13.  *    $Header: /private/postgres/src/storage/lmgr/RCS/lmgr.c,v 1.33 1992/07/13 03:36:18 hong Exp $
  14.  * ----------------------------------------------------------------
  15.  */
  16.  
  17. /* #define LOCKDEBUGALL    1 */
  18. /* #define LOCKDEBUG    1 */
  19.  
  20. #ifdef    LOCKDEBUGALL
  21. #define LOCKDEBUG    1
  22. #endif  LOCKDEBUGALL
  23.  
  24. #include "tmp/postgres.h"
  25.  
  26.  RcsId("$Header: /private/postgres/src/storage/lmgr/RCS/lmgr.c,v 1.33 1992/07/13 03:36:18 hong Exp $");
  27.  
  28.  
  29. #include "access/heapam.h"
  30. #include "access/htup.h"
  31. #include "access/relscan.h"
  32. #include "access/skey.h"
  33. #include "access/tqual.h"
  34. #include "access/xact.h"
  35.  
  36. #include "storage/block.h"
  37. #include "storage/buf.h"
  38. #include "storage/itemptr.h"
  39. #include "storage/bufpage.h"
  40. #include "storage/pagenum.h"
  41. #include "storage/part.h"
  42. #include "storage/multilev.h"
  43. #include "storage/lmgr.h"
  44.  
  45. #include "utils/log.h"
  46. #include "utils/rel.h"
  47.  
  48. #include "catalog/catname.h"
  49. #include "catalog/pg_relation.h"
  50.  
  51. #include "nodes/mnodes.h"
  52. /* ----------------
  53.  *    
  54.  * ----------------
  55.  */
  56. #define MaxRetries    4    /* XXX about 1/4 minute--a hack */
  57.  
  58. #define IntentReadRelationLock    0x0100
  59. #define ReadRelationLock    0x0200
  60. #define IntentWriteRelationLock    0x0400
  61. #define WriteRelationLock    0x0800
  62. #define IntentReadPageLock    0x1000
  63. #define ReadTupleLock        0x2000
  64.  
  65. #define TupleLevelLockCountMask    0x000f
  66.  
  67. #define TupleLevelLockLimit    10
  68.  
  69. extern ObjectId    MyDatabaseId;
  70.  
  71. static LRelId    VariableRelationLRelId =
  72. { VariableRelationId, InvalidObjectId };
  73.  
  74. /* ----------------
  75.  *    RelationGetLRelId
  76.  * ----------------
  77.  */
  78. #ifdef    LOCKDEBUG
  79. #define LOCKDEBUG_10 \
  80.     elog(NOTICE, "RelationGetLRelId(%s) invalid lockInfo", \
  81.      RelationGetRelationName(relation));
  82. #else
  83. #define LOCKDEBUG_10
  84. #endif    LOCKDEBUG
  85.     
  86. LRelId
  87. RelationGetLRelId(relation)
  88.     Relation    relation;
  89. {
  90.     LockInfo    linfo;
  91.     
  92.     /* ----------------
  93.      *    sanity checks
  94.      * ----------------
  95.      */
  96.     Assert(RelationIsValid(relation));
  97.     linfo = (LockInfo) relation->lockInfo;
  98.  
  99.     /* ----------------
  100.      *    initialize lock info if necessary
  101.      * ----------------
  102.      */
  103.     if (! LockInfoIsValid(linfo)) {
  104.     LOCKDEBUG_10;
  105.     RelationInitLockInfo(relation);
  106.     linfo = (LockInfo) relation->lockInfo;
  107.     }
  108.     
  109.     /* ----------------
  110.      * XXX hack to prevent problems during
  111.      * VARIABLE relation initialization
  112.      * ----------------
  113.      */
  114.     if (NameIsEqual(RelationGetRelationName(relation),
  115.             VariableRelationName)) {
  116.     return (VariableRelationLRelId);
  117.     }
  118.     
  119.     return (linfo->lRelId);
  120. }
  121.  
  122. /* ----------------
  123.  *    LRelIdGetDatabaseId
  124.  *
  125.  * Note: The argument may not be correct, if it is not used soon
  126.  *     after it is created.
  127.  * ----------------
  128.  */
  129. ObjectId
  130. LRelIdGetDatabaseId(lRelId)
  131.     LRelId    lRelId;
  132. {
  133.     return (lRelId.dbId);
  134. }
  135.  
  136.  
  137. /* ----------------
  138.  *    LRelIdGetRelationId
  139.  * ----------------
  140.  */
  141. ObjectId
  142. LRelIdGetRelationId(lRelId)
  143.     LRelId    lRelId;
  144. {
  145.     return (lRelId.relId);
  146. }
  147.  
  148. /* ----------------
  149.  *    DatabaseIdIsMyDatabaseId
  150.  * ----------------
  151.  */
  152. bool
  153. DatabaseIdIsMyDatabaseId(databaseId)
  154.     ObjectId    databaseId;
  155. {
  156.     return (bool)
  157.     (!ObjectIdIsValid(databaseId) || databaseId == MyDatabaseId);
  158. }
  159.  
  160. /* ----------------
  161.  *    LRelIdContainsMyDatabaseId
  162.  * ----------------
  163.  */
  164. bool
  165. LRelIdContainsMyDatabaseId(lRelId)
  166.     LRelId    lRelId;
  167. {
  168.     return (bool)
  169.     (!ObjectIdIsValid(lRelId.dbId) || lRelId.dbId == MyDatabaseId);
  170. }
  171.  
  172. /* ----------------
  173.  *    RelationInitLockInfo
  174.  *
  175.  *     XXX processingVariable is a hack to prevent problems during
  176.  *     VARIABLE relation initialization.
  177.  * ----------------
  178.  */
  179. void
  180. RelationInitLockInfo(relation)
  181.     Relation    relation;
  182. {
  183.     LockInfo        info;
  184.     char         *relname;
  185.     ObjectId        relationid;
  186.     bool        processingVariable;
  187.     extern ObjectId    MyDatabaseId;        /* XXX use include */
  188.     extern GlobalMemory CacheCxt;
  189.     
  190.     /* ----------------
  191.      *    sanity checks
  192.      * ----------------
  193.      */
  194.     Assert(RelationIsValid(relation));
  195.     Assert(ObjectIdIsValid(RelationGetRelationId(relation)));
  196.  
  197.     /* ----------------
  198.      *    get information from relation descriptor
  199.      * ----------------
  200.      */
  201.     info = (LockInfo) relation->lockInfo;
  202.     relname = (char *) RelationGetRelationName(relation);
  203.     relationid = RelationGetRelationId(relation);
  204.     processingVariable = NameIsEqual((Name) relname, VariableRelationName);
  205.     
  206.     /* ----------------
  207.      *    create a new lockinfo if not already done
  208.      * ----------------
  209.      */
  210.     if (! PointerIsValid(info)) 
  211.     {
  212.     MemoryContext oldcxt;
  213.  
  214.     oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
  215.     info = (LockInfo)palloc(sizeof(LockInfoData));
  216.     MemoryContextSwitchTo(oldcxt);
  217.     }
  218.     else if (processingVariable) {
  219.     if (IsTransactionState()) {
  220.         TransactionIdStore(GetCurrentTransactionId(),
  221.                    &info->transactionIdData);
  222.     }
  223.     info->flags = 0x0;
  224.     return;        /* prevent an infinite loop--still true? */
  225.     }
  226.     else if (info->initialized)
  227.     {
  228.         /* ------------
  229.          *  If we've already initialized we're done.
  230.          * ------------
  231.          */
  232.     return;
  233.     }
  234.  
  235.     /* ----------------
  236.      *    initialize lockinfo.dbId and .relId appropriately
  237.      * ----------------
  238.      */
  239.     if (NameIsSharedSystemRelationName((Name) relname))
  240.     LRelIdAssign(&info->lRelId, InvalidObjectId, relationid);
  241.     else
  242.     LRelIdAssign(&info->lRelId, MyDatabaseId, relationid);
  243.     
  244.     /* ----------------
  245.      *    store the transaction id in the lockInfo field
  246.      * ----------------
  247.      */
  248.     if (processingVariable)
  249.     TransactionIdStore(AmiTransactionId,
  250.                &info->transactionIdData);
  251.     else if (IsTransactionState()) 
  252.     TransactionIdStore(GetCurrentTransactionId(),
  253.                &info->transactionIdData);
  254.     else
  255.     PointerStoreInvalidTransactionId((Pointer)&(info->transactionIdData));
  256.     
  257.     /* ----------------
  258.      *    initialize rest of lockinfo
  259.      * ----------------
  260.      */
  261.     info->flags = 0x0;
  262.     info->initialized =    (bool)true;
  263.     relation->lockInfo = (Pointer) info;
  264. }
  265.  
  266. /* ----------------
  267.  *    RelationDiscardLockInfo
  268.  * ----------------
  269.  */
  270. #ifdef    LOCKDEBUG
  271. #define LOCKDEBUG_20 \
  272.     elog(DEBUG, "DiscardLockInfo: NULL relation->lockInfo")
  273. #else
  274. #define LOCKDEBUG_20
  275. #endif    LOCKDEBUG
  276.    
  277. void
  278. RelationDiscardLockInfo(relation)
  279.     Relation    relation;
  280. {
  281.     if (! LockInfoIsValid(relation->lockInfo)) {
  282.     LOCKDEBUG_20;
  283.     return;
  284.     }
  285.     
  286.     delete(relation->lockInfo);    /* XXX pfree((Pointer)relation->lockInfo) */
  287. }
  288.  
  289. /* ----------------
  290.  *    RelationSetLockForDescriptorOpen
  291.  * ----------------
  292.  */
  293. #ifdef    LOCKDEBUGALL
  294. #define LOCKDEBUGALL_30 \
  295.     elog(DEBUG, "RelationSetLockForDescriptorOpen(%s[%d,%d]) called", \
  296.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
  297. #else
  298. #define LOCKDEBUGALL_30
  299. #endif    LOCKDEBUGALL
  300.  
  301. void
  302. RelationSetLockForDescriptorOpen(relation)
  303.     Relation    relation;
  304. {
  305.     /* ----------------
  306.      *    sanity checks
  307.      * ----------------
  308.      */
  309.     Assert(RelationIsValid(relation));
  310.     if (LockingDisabled())
  311.     return;
  312.  
  313.     LOCKDEBUGALL_30;
  314.  
  315.     /* ----------------
  316.      * read lock catalog tuples which compose the relation descriptor
  317.      * XXX race condition? XXX For now, do nothing.
  318.      * ----------------
  319.      */
  320. }
  321.  
  322. /* ----------------
  323.  *    RelationSetLockForRead
  324.  * ----------------
  325.  */
  326. #ifdef    LOCKDEBUG
  327. #define LOCKDEBUG_40 \
  328.     elog(DEBUG, "RelationSetLockForRead(%s[%d,%d]) called", \
  329.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
  330. #else
  331. #define LOCKDEBUG_40
  332. #endif    LOCKDEBUG
  333.    
  334. void
  335. RelationSetLockForRead(relation)
  336.     Relation    relation;
  337. {
  338.     LockInfo    linfo;
  339.     TransactionId curXact;
  340.  
  341.     /* ----------------
  342.      *    sanity checks
  343.      * ----------------
  344.      */
  345.     Assert(RelationIsValid(relation));
  346.     if (LockingDisabled())
  347.     return;
  348.     
  349.     LOCKDEBUG_40;
  350.  
  351.     /* ----------------
  352.      * If we don't have lock info on the reln just go ahead and
  353.      * lock it without trying to short circuit the lock manager.
  354.      * ----------------
  355.      */
  356.     if (!LockInfoIsValid(relation->lockInfo))
  357.     {
  358.     RelationInitLockInfo(relation);
  359.     linfo = (LockInfo) relation->lockInfo;
  360.     linfo->flags |= ReadRelationLock;
  361.         MultiLockReln(linfo, READ_LOCK);
  362.     return;
  363.     }
  364.     else
  365.         linfo = (LockInfo) relation->lockInfo;
  366.  
  367.     MultiLockReln(linfo, READ_LOCK);
  368. }
  369.  
  370. /* ----------------
  371.  *    RelationUnsetLockForRead
  372.  * ----------------
  373.  */
  374. #ifdef    LOCKDEBUG
  375. #define LOCKDEBUG_50 \
  376.     elog(DEBUG, "RelationUnsetLockForRead(%s[%d,%d]) called", \
  377.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
  378. #else
  379. #define LOCKDEBUG_50
  380. #endif    LOCKDEBUG
  381.  
  382. void
  383. RelationUnsetLockForRead(relation)
  384.     Relation relation;
  385. {
  386.     LockInfo    linfo;
  387.  
  388.     /* ----------------
  389.      *    sanity check
  390.      * ----------------
  391.      */
  392.     Assert(RelationIsValid(relation));
  393.     if (LockingDisabled())
  394.     return;
  395.     
  396.     linfo = (LockInfo) relation->lockInfo;
  397.  
  398.     /* ----------------
  399.      * If we don't have lock info on the reln just go ahead and
  400.      * release it.
  401.      * ----------------
  402.      */
  403.     if (!LockInfoIsValid(linfo))
  404.     {
  405.         elog(WARN, 
  406.             "Releasing a lock on %s with invalid lock information",
  407.             RelationGetRelationName(relation));
  408.     }
  409.  
  410.     MultiReleaseReln(linfo, READ_LOCK);
  411. }
  412.  
  413. /* ----------------
  414.  *    RelationSetLockForWrite(relation)
  415.  * ----------------
  416.  */
  417. #ifdef    LOCKDEBUG
  418. #define LOCKDEBUG_60 \
  419.     elog(DEBUG, "RelationSetLockForWrite(%s[%d,%d]) called", \
  420.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
  421. #else
  422. #define LOCKDEBUG_60
  423. #endif    LOCKDEBUG
  424.  
  425. void
  426. RelationSetLockForWrite(relation)
  427.     Relation    relation;
  428. {
  429.     LockInfo    linfo;
  430.     TransactionId curXact;
  431.     
  432.     /* ----------------
  433.      *    sanity checks
  434.      * ----------------
  435.      */
  436.     Assert(RelationIsValid(relation));
  437.     if (LockingDisabled())
  438.     return;
  439.     
  440.     LOCKDEBUG_60;
  441.     
  442.     /* ----------------
  443.      * If we don't have lock info on the reln just go ahead and
  444.      * lock it without trying to short circuit the lock manager.
  445.      * ----------------
  446.      */
  447.     if (!LockInfoIsValid(relation->lockInfo))
  448.     {
  449.     RelationInitLockInfo(relation);
  450.         linfo = (LockInfo) relation->lockInfo;
  451.     linfo->flags |= WriteRelationLock;
  452.         MultiLockReln(linfo, WRITE_LOCK);
  453.     return;
  454.     }
  455.     else
  456.         linfo = (LockInfo) relation->lockInfo;
  457.  
  458.     MultiLockReln(linfo, WRITE_LOCK);
  459. }
  460.  
  461. /* ----------------
  462.  *    RelationUnsetLockForWrite
  463.  * ----------------
  464.  */
  465. #ifdef    LOCKDEBUG
  466. #define LOCKDEBUG_70 \
  467.     elog(DEBUG, "RelationUnsetLockForWrite(%s[%d,%d]) called", \
  468.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId);
  469. #else
  470. #define LOCKDEBUG_70
  471. #endif    LOCKDEBUG
  472.  
  473. void
  474. RelationUnsetLockForWrite(relation)
  475.     Relation relation;
  476. {
  477.     LockInfo    linfo;
  478.  
  479.     /* ----------------
  480.      *    sanity checks
  481.      * ----------------
  482.      */
  483.     Assert(RelationIsValid(relation));
  484.     if (LockingDisabled()) {
  485.     return;
  486.     }
  487.  
  488.     linfo = (LockInfo) relation->lockInfo;
  489.  
  490.     if (!LockInfoIsValid(linfo))
  491.     {
  492.         elog(WARN, 
  493.             "Releasing a lock on %s with invalid lock information",
  494.             RelationGetRelationName(relation));
  495.     }
  496.  
  497.     MultiReleaseReln(linfo, WRITE_LOCK);
  498. }
  499.  
  500. /* ----------------
  501.  *    RelationSetLockForTupleRead
  502.  * ----------------
  503.  */
  504. #ifdef    LOCKDEBUG
  505. #define LOCKDEBUG_80 \
  506.     elog(DEBUG, "RelationSetLockForTupleRead(%s[%d,%d], 0x%x) called", \
  507.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, \
  508.      itemPointer)
  509. #define LOCKDEBUG_81 \
  510.     elog(DEBUG, "RelationSetLockForTupleRead() escalating");
  511. #else
  512. #define LOCKDEBUG_80
  513. #define LOCKDEBUG_81
  514. #endif    LOCKDEBUG
  515.  
  516. void
  517. RelationSetLockForTupleRead(relation, itemPointer)
  518.     Relation    relation;
  519.     ItemPointer    itemPointer;
  520. {
  521.     LockInfo    linfo;
  522.     TransactionId curXact;
  523.     
  524.     /* ----------------
  525.      *    sanity checks
  526.      * ----------------
  527.      */
  528.     Assert(RelationIsValid(relation));
  529.     if (LockingDisabled())
  530.     return;
  531.  
  532.     LOCKDEBUG_80;
  533.     
  534.     /* ---------------------
  535.      * If our lock info is invalid don't bother trying to short circuit
  536.      * the lock manager.
  537.      * ---------------------
  538.      */
  539.     if (!LockInfoIsValid(relation->lockInfo))
  540.     {
  541.     RelationInitLockInfo(relation);
  542.     linfo = (LockInfo) relation->lockInfo;
  543.     linfo->flags |=
  544.                 IntentReadRelationLock |
  545.         IntentReadPageLock |
  546.         ReadTupleLock;
  547.         MultiLockTuple(linfo, itemPointer, READ_LOCK);
  548.     return;
  549.     }
  550.     else
  551.         linfo = (LockInfo) relation->lockInfo;
  552.  
  553.     /* ----------------
  554.      *    no need to set a lower granularity lock
  555.      * ----------------
  556.      */
  557.     curXact = GetCurrentTransactionId();
  558.     if ((linfo->flags & ReadRelationLock) &&
  559.     TransactionIdEquals(curXact, linfo->transactionIdData))
  560.     {
  561.     return;
  562.     }
  563.     
  564.     /* ----------------
  565.      * If we don't already have a tuple lock this transaction
  566.      * ----------------
  567.      */
  568.     if (!( (linfo->flags & ReadTupleLock) &&
  569.            TransactionIdEquals(curXact, linfo->transactionIdData) )) {
  570.     
  571.     linfo->flags |=
  572.             IntentReadRelationLock |
  573.         IntentReadPageLock |
  574.         ReadTupleLock;
  575.     
  576.     /* clear count */
  577.     linfo->flags &= ~TupleLevelLockCountMask;
  578.     
  579.     } else {
  580.     if (TupleLevelLockLimit == (TupleLevelLockCountMask &
  581.                     linfo->flags)) {
  582.         LOCKDEBUG_81;
  583.         
  584.         /* escalate */
  585.         MultiLockReln(linfo, READ_LOCK);
  586.         
  587.         /* clear count */
  588.         linfo->flags &= ~TupleLevelLockCountMask;
  589.         return;
  590.     }
  591.     
  592.     /* increment count */
  593.     linfo->flags =
  594.         (linfo->flags & ~TupleLevelLockCountMask) |
  595.         (1 + (TupleLevelLockCountMask & linfo->flags));
  596.     }
  597.  
  598.     TransactionIdStore(curXact, &linfo->transactionIdData);
  599.  
  600.     /* ----------------
  601.      * Lock the tuple.
  602.      * ----------------
  603.      */
  604.     MultiLockTuple(linfo, itemPointer, READ_LOCK);
  605. }
  606.  
  607. /* ----------------
  608.  *    RelationSetLockForReadPage
  609.  * ----------------
  610.  */
  611. #ifdef    LOCKDEBUG
  612. #define LOCKDEBUG_90 \
  613.     elog(DEBUG, "RelationSetLockForReadPage(%s[%d,%d], %d, @%d) called", \
  614.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, \
  615.      partition, page);
  616. #else
  617. #define LOCKDEBUG_90
  618. #endif    LOCKDEBUG
  619.  
  620. void
  621. RelationSetLockForReadPage(relation, partition, itemPointer)
  622.     Relation        relation;
  623.     PagePartition    partition;    /* XXX not used */
  624.     ItemPointer        itemPointer;
  625. {
  626.     /* ----------------
  627.      *    sanity check
  628.      * ----------------
  629.      */
  630.     Assert(RelationIsValid(relation));
  631.     if (LockingDisabled())
  632.     return;
  633.     
  634.     /* ---------------
  635.      * Make sure linfo is initialized
  636.      * ---------------
  637.      */
  638.     if (!LockInfoIsValid(relation->lockInfo))
  639.     RelationInitLockInfo(relation);
  640.  
  641.     /* ----------------
  642.      *    attempt to set lock
  643.      * ----------------
  644.      */
  645.     MultiLockPage((LockInfo) (relation->lockInfo), itemPointer, READ_LOCK);
  646. }
  647.  
  648. /* ----------------
  649.  *    RelationSetLockForWritePage
  650.  * ----------------
  651.  */
  652. #ifdef    LOCKDEBUG
  653. #define LOCKDEBUG_100 \
  654.     elog(DEBUG, "RelationSetLockForWritePage(%s[%d,%d], %d, @%d) called", \
  655.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, \
  656.      partition, page);
  657. #else
  658. #define LOCKDEBUG_100
  659. #endif    LOCKDEBUG
  660.  
  661. void
  662. RelationSetLockForWritePage(relation, partition, itemPointer)
  663.     Relation        relation;
  664.     PagePartition    partition;    /* XXX not used */
  665.     ItemPointer        itemPointer;
  666. {
  667.     /* ----------------
  668.      *    sanity checks
  669.      * ----------------
  670.      */
  671.     Assert(RelationIsValid(relation));
  672.     if (LockingDisabled())
  673.     return;
  674.  
  675.     /* ---------------
  676.      * Make sure linfo is initialized
  677.      * ---------------
  678.      */
  679.     if (!LockInfoIsValid(relation->lockInfo))
  680.     RelationInitLockInfo(relation);
  681.  
  682.     /* ----------------
  683.      *    attempt to set lock
  684.      * ----------------
  685.      */
  686.     MultiLockPage((LockInfo) relation->lockInfo, itemPointer, WRITE_LOCK);
  687. }
  688.  
  689. /* ----------------
  690.  *    RelationUnsetLockForReadPage
  691.  * ----------------
  692.  */
  693. #ifdef    LOCKDEBUG
  694. #define LOCKDEBUG_110 \
  695.     elog(DEBUG, "RelationUnsetLockForReadPage(%s[%d,%d], %d, %d) called", \
  696.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, \
  697.      partition, page)
  698. #else
  699. #define LOCKDEBUG_110
  700. #endif    LOCKDEBUG
  701.  
  702. void
  703. RelationUnsetLockForReadPage(relation, partition, itemPointer)
  704.     Relation    relation;
  705.     PagePartition    partition;
  706.     ItemPointer    itemPointer;
  707. {
  708.     /* ----------------
  709.      *    sanity checks
  710.      * ----------------
  711.      */
  712.     Assert(RelationIsValid(relation));
  713.     if (LockingDisabled())
  714.     return;
  715.  
  716.     if (!LockInfoIsValid(relation->lockInfo))
  717.         elog(WARN, 
  718.             "Releasing a lock on %s with invalid lock information",
  719.             RelationGetRelationName(relation));
  720.  
  721.     MultiReleasePage((LockInfo) relation->lockInfo, itemPointer, READ_LOCK);
  722. }
  723.  
  724. /* ----------------
  725.  *    RelationUnsetLockForWritePage
  726.  * ----------------
  727.  */
  728. #ifdef    LOCKDEBUG
  729. #define LOCKDEBUG_120 \
  730.     elog(DEBUG, "RelationUnsetLockForWritePage(%s[%d,%d], %d, @%d) called", \
  731.      RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, \
  732.      partition, page)
  733. #else
  734. #define LOCKDEBUG_120
  735. #endif    LOCKDEBUG
  736.  
  737. void
  738. RelationUnsetLockForWritePage(relation, partition, itemPointer)
  739.     Relation        relation;
  740.     PagePartition    partition;
  741.     ItemPointer        itemPointer;
  742. {
  743.     /* ----------------
  744.      *    sanity checks
  745.      * ----------------
  746.      */
  747.     Assert(RelationIsValid(relation));
  748.     if (LockingDisabled())
  749.     return;
  750.     
  751.     if (!LockInfoIsValid(relation->lockInfo))
  752.         elog(WARN, 
  753.             "Releasing a lock on %s with invalid lock information",
  754.             RelationGetRelationName(relation));
  755.  
  756.     MultiReleasePage((LockInfo) relation->lockInfo, itemPointer, WRITE_LOCK);
  757. }
  758.  
  759. /*
  760.  * Set a single level write page lock.  Assumes that you already
  761.  * have a write intent lock on the relation.
  762.  */
  763. RelationSetSingleWLockPage(relation, partition, itemPointer)
  764.     Relation relation;
  765.     PagePartition       partition;
  766.     ItemPointer         itemPointer;
  767. {
  768.  
  769.     /* ----------------
  770.      *    sanity checks
  771.      * ----------------
  772.      */
  773.     Assert(RelationIsValid(relation));
  774.     if (LockingDisabled())
  775.     return;
  776.     
  777.     if (!LockInfoIsValid(relation->lockInfo))
  778.         elog(WARN, 
  779.             "Releasing a lock on %s with invalid lock information",
  780.             RelationGetRelationName(relation));
  781.  
  782.     SingleLockPage(relation->lockInfo, itemPointer, WRITE_LOCK, !UNLOCK);
  783. }
  784.  
  785. /*
  786.  * Unset a single level write page lock
  787.  */
  788. RelationUnsetSingleWLockPage(relation, partition, itemPointer)
  789.     Relation relation;
  790.     PagePartition       partition;
  791.     ItemPointer         itemPointer;
  792. {
  793.  
  794.     /* ----------------
  795.      *    sanity checks
  796.      * ----------------
  797.      */
  798.     Assert(RelationIsValid(relation));
  799.     if (LockingDisabled())
  800.     return;
  801.     
  802.     if (!LockInfoIsValid(relation->lockInfo))
  803.         elog(WARN, 
  804.             "Releasing a lock on %s with invalid lock information",
  805.             RelationGetRelationName(relation));
  806.  
  807.     SingleLockPage(relation->lockInfo, itemPointer, WRITE_LOCK, UNLOCK);
  808. }
  809.  
  810. /*
  811.  * Set a single level read page lock.  Assumes you already have a read
  812.  * intent lock set on the relation.
  813.  */
  814. RelationSetSingleRLockPage(relation, partition, itemPointer)
  815.     Relation relation;
  816.     PagePartition       partition;
  817.     ItemPointer         itemPointer;
  818. {
  819.  
  820.     /* ----------------
  821.      *    sanity checks
  822.      * ----------------
  823.      */
  824.     Assert(RelationIsValid(relation));
  825.     if (LockingDisabled())
  826.     return;
  827.     
  828.     if (!LockInfoIsValid(relation->lockInfo))
  829.         elog(WARN, 
  830.             "Releasing a lock on %s with invalid lock information",
  831.             RelationGetRelationName(relation));
  832.  
  833.     SingleLockPage(relation->lockInfo, itemPointer, READ_LOCK, !UNLOCK);
  834. }
  835.  
  836. /* 
  837.  * Unset a single level read page lock.
  838.  */
  839. RelationUnsetSingleRLockPage(relation, partition, itemPointer)
  840.     Relation relation;
  841.     PagePartition       partition;
  842.     ItemPointer         itemPointer;
  843. {
  844.  
  845.     /* ----------------
  846.      *    sanity checks
  847.      * ----------------
  848.      */
  849.     Assert(RelationIsValid(relation));
  850.     if (LockingDisabled())
  851.     return;
  852.     
  853.     if (!LockInfoIsValid(relation->lockInfo))
  854.         elog(WARN, 
  855.             "Releasing a lock on %s with invalid lock information",
  856.             RelationGetRelationName(relation));
  857.  
  858.     SingleLockPage(relation->lockInfo, itemPointer, READ_LOCK, UNLOCK);
  859. }
  860.  
  861. /*
  862.  * Set a read intent lock on a relation.
  863.  *
  864.  * Usually these are set in a multi-level table when you acquiring a
  865.  * page level lock.  i.e. To acquire a lock on a page you first acquire
  866.  * an intent lock on the entire relation.  Acquiring an intent lock along
  867.  * allows one to use the single level locking routines later.  Good for
  868.  * index scans that do a lot of page level locking.
  869.  */
  870. RelationSetRIntentLock(relation)
  871.     Relation relation;
  872. {
  873.     /* -----------------
  874.      * Sanity check
  875.      * -----------------
  876.      */
  877.     Assert(RelationIsValid(relation));
  878.     if (LockingDisabled())
  879.     return;
  880.  
  881.     if (!LockInfoIsValid(relation->lockInfo))
  882.     RelationInitLockInfo(relation);
  883.  
  884.     SingleLockReln(relation->lockInfo, READ_LOCK+INTENT, !UNLOCK);
  885. }
  886.  
  887. /*
  888.  * Unset a read intent lock on a relation
  889.  */
  890. RelationUnsetRIntentLock(relation)
  891.     Relation relation;
  892. {
  893.     /* -----------------
  894.      * Sanity check
  895.      * -----------------
  896.      */
  897.     Assert(RelationIsValid(relation));
  898.     if (LockingDisabled())
  899.     return;
  900.  
  901.     if (!LockInfoIsValid(relation->lockInfo))
  902.     RelationInitLockInfo(relation);
  903.  
  904.     SingleLockReln(relation->lockInfo, READ_LOCK+INTENT, UNLOCK);
  905. }
  906.  
  907. /*
  908.  * Set a write intent lock on a relation. For a more complete explanation
  909.  * see RelationSetRIntentLock()
  910.  */
  911. RelationSetWIntentLock(relation)
  912.     Relation relation;
  913. {
  914.     /* -----------------
  915.      * Sanity check
  916.      * -----------------
  917.      */
  918.     Assert(RelationIsValid(relation));
  919.     if (LockingDisabled())
  920.     return;
  921.  
  922.     if (!LockInfoIsValid(relation->lockInfo))
  923.     RelationInitLockInfo(relation);
  924.  
  925.     SingleLockReln(relation->lockInfo, WRITE_LOCK+INTENT, !UNLOCK);
  926. }
  927.  
  928. /*
  929.  * Unset a write intent lock.
  930.  */
  931. RelationUnsetWIntentLock(relation)
  932.     Relation relation;
  933. {
  934.     /* -----------------
  935.      * Sanity check
  936.      * -----------------
  937.      */
  938.     Assert(RelationIsValid(relation));
  939.     if (LockingDisabled())
  940.     return;
  941.  
  942.     if (!LockInfoIsValid(relation->lockInfo))
  943.     RelationInitLockInfo(relation);
  944.  
  945.     SingleLockReln(relation->lockInfo, WRITE_LOCK+INTENT, UNLOCK);
  946. }
  947.  
  948. /*
  949.  * Extend locks are used primarily in tertiary storage devices such as
  950.  * a WORM disk jukebox.  Sometimes need exclusive access to extend a 
  951.  * file by a block.
  952.  */
  953. RelationSetLockForExtend(relation)
  954.     Relation relation;
  955. {
  956.     /* -----------------
  957.      * Sanity check
  958.      * -----------------
  959.      */
  960.     Assert(RelationIsValid(relation));
  961.     if (LockingDisabled())
  962.     return;
  963.  
  964.     if (!LockInfoIsValid(relation->lockInfo))
  965.     RelationInitLockInfo(relation);
  966.  
  967.     MultiLockReln((LockInfo) relation->lockInfo, EXTEND_LOCK);
  968. }
  969.  
  970. RelationUnsetLockForExtend(relation)
  971.     Relation relation;
  972. {
  973.     /* -----------------
  974.      * Sanity check
  975.      * -----------------
  976.      */
  977.     Assert(RelationIsValid(relation));
  978.     if (LockingDisabled())
  979.     return;
  980.  
  981.     if (!LockInfoIsValid(relation->lockInfo))
  982.     RelationInitLockInfo(relation);
  983.  
  984.     MultiReleaseReln((LockInfo) relation->lockInfo, EXTEND_LOCK);
  985. }
  986.  
  987. /* 
  988.  * Create an LRelid --- Why not just pass in a pointer to the storage?
  989.  */
  990. void
  991. LRelIdAssign(lRelId, dbId, relId)
  992.      LRelId    *lRelId;
  993.      ObjectId     dbId;
  994.      ObjectId     relId;
  995. {   
  996.     lRelId->dbId = dbId;
  997.     lRelId->relId = relId;
  998. }
  999.